# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from openerp.osv import fields, osv
from openerp.tools.translate import _
from openerp import netsvc

class account_move_line(osv.osv):

    _inherit = 'account.move.line'

    def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
        if context is None:
            context = {}
        user_company_currency_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
        if context.get('type') and context.get('status'):
            if context.get('type') == 'payment':
                account_type = 'payable'
            else:
                account_type = 'receivable'
 
            if context.get('status') == 'debit':
                status = ('debit', '>', 0)
            else:
                status = ('credit', '>', 0)
            if context.get('multi_partner'):
                partner_id = context.get('multi_partner')
                partner_data = self.pool.get('res.partner').browse(cr, uid, partner_id)
                parent_partner = False
                prt1_ids = []
                if partner_data.parent_id:
                    parent_partner = True
                    parent_id = partner_data.parent_id.id
                    cr.execute('select id from res_partner where parent_id = %d'% parent_id)
                    res1 = cr.fetchall()
                    for r in res1:
                        prt1_ids.append(r[0])
            else:
                partner_id = False
                parent_partner = False
 
            move_line_pool = self.pool.get('account.move.line')
            if parent_partner:
                account_move_lines = move_line_pool.browse(cr, uid, move_line_pool.search(cr, uid, [status,('state','=','valid'), ('account_id.type', '=', account_type), ('reconcile_id', '=', False), ('partner_id','in',prt1_ids)], context=None), context=context)
            else:
                if partner_id:
                    account_move_lines = move_line_pool.browse(cr, uid, move_line_pool.search(cr, uid, [status, ('state','=','valid'), ('account_id.type', '=', account_type), ('reconcile_id', '=', False), ('partner_id', '=', partner_id)], context=None), context=context) 
                else:
                    account_move_lines = move_line_pool.browse(cr, uid, move_line_pool.search(cr, uid, [status, ('state','=','valid'), ('account_id.type', '=', account_type), ('reconcile_id', '=', False)], context=None), context=context)
 
            move_line_ids = []
            for line in account_move_lines:
                if line.credit and line.reconcile_partial_id and line.is_depo != True and context.get('type') == 'receipt':
                    if line.is_refund != True:
                        continue
                if line.debit and line.reconcile_partial_id and line.is_refund == True and context.get('type') == 'receipt':
                    continue
                if line.debit and line.reconcile_partial_id and line.is_depo == True and context.get('type') == 'receipt':
                    continue
 
                if line.debit and line.reconcile_partial_id and line.is_depo != True and context.get('type') == 'payment':
                     if line.is_refund != True:
                        continue
                if line.credit and line.reconcile_partial_id and line.is_refund == True and context.get('type') == 'payment':
                    continue
                if line.credit and line.reconcile_partial_id and line.is_depo == True and context.get('type') == 'payment':
                    continue
                move_line_ids.append(line.id)
            args.append(('id','in',move_line_ids))
 
        return super(account_move_line, self).search(cr, uid, args, offset, limit,
                order, context=context, count=count)
# 
    def _currency(self, cursor, user, ids, name, args, context=None):
        res = {}
        res_currency_obj = self.pool.get('res.currency')
        res_users_obj = self.pool.get('res.users')
        default_currency = res_users_obj.browse(cursor, user,
                user, context=context).company_id.currency_id
        for statement in self.browse(cursor, user, ids, context=context):
            currency = statement.currency_id
            if not currency:
                currency = default_currency
            res[statement.id] = currency.id
        currency_names = {}
        for currency_id, currency_name in res_currency_obj.name_get(cursor,
                user, [x for x in res.values()], context=context):
            currency_names[currency_id] = currency_name
        for statement_id in res.keys():
            currency_id = res[statement_id]
            res[statement_id] = (currency_id, currency_names[currency_id])
        return res
# 
    def _amount_residual(self, cr, uid, ids, field_names, args, context=None):
        """
           This function returns the residual amount on a receivable or payable account.move.line.
           By default, it returns an amount in the currency of this journal entry (maybe different
           of the company currency), but if you pass 'residual_in_company_currency' = True in the
           context then the returned amount will be in company currency.
        """
        res = {}
        if context is None:
            context = {}
        cur_obj = self.pool.get('res.currency')
        acc_move_recon_obj = self.pool.get('account.move.reconcile')
        for move_line in self.browse(cr, uid, ids, context=context):
            res[move_line.id] = {
                'amount_original':0.0,
                'amount_residual': 0.0,
                'amount_residual_currency': 0.0,
                'amount_res': 0.0,
            }
 
            if move_line.reconcile_id:
                continue
            if not move_line.account_id.type in ('payable', 'receivable'):
                #this function does not suport to be used on move lines not related to payable or receivable accounts
                continue
 
            if move_line.currency_id:
                move_line_total = move_line.amount_currency
                sign = move_line.amount_currency < 0 and -1 or 1
            else:
                move_line_total = move_line.debit - move_line.credit
                sign = (move_line.debit - move_line.credit) < 0 and -1 or 1
            amount_original = move_line_total
            line_total_in_company_currency =  move_line.debit - move_line.credit
            context_unreconciled = context.copy()
            if move_line.reconcile_partial_id:
                acc_move_recon_id = acc_move_recon_obj.browse(cr, uid, move_line.reconcile_partial_id.id, context=None)
 
                for payment_line in acc_move_recon_id.line_partial_ids:
                    if payment_line.id == move_line.id:
                        continue
                    if payment_line.currency_id and move_line.currency_id and payment_line.currency_id.id == move_line.currency_id.id:
                            move_line_total += payment_line.amount_currency
                    else:
                        if move_line.currency_id:
                            context_unreconciled.update({'date': payment_line.date})
                            amount_in_foreign_currency = round(cur_obj.compute(cr, uid, move_line.company_id.currency_id.id, move_line.currency_id.id, (payment_line.debit - payment_line.credit), round=False, context=context_unreconciled),self.pool.get('decimal.precision').precision_get(cr, uid, 'Account'))
                            move_line_total += amount_in_foreign_currency
                        else:
                            move_line_total += (payment_line.debit - payment_line.credit)
                    line_total_in_company_currency += (payment_line.debit - payment_line.credit)
 
            result = move_line_total
#            res[move_line.id]['amount_residual_currency'] =  sign * (move_line.currency_id and self.pool.get('res.currency').round(cr, uid, move_line.currency_id, result) or result)
            res[move_line.id]['amount_original'] = sign * round((move_line.currency_id and self.pool.get('res.currency').round(cr, uid, move_line.currency_id, amount_original) or amount_original),self.pool.get('decimal.precision').precision_get(cr, uid, 'Account'))
 
 
 
            res[move_line.id]['amount_residual'] = sign * line_total_in_company_currency
            ctx = {'date': move_line.date or move_line.date}
             
            res[move_line.id]['amount_residual_currency'] = sign * (move_line.currency_id and self.pool.get('res.currency').round(cr, uid, move_line.currency_id, result) or result)
            if move_line.currency_id:
                move_line_res = abs((move_line.currency_id and self.pool.get('res.currency').round(cr, uid, move_line.currency_id, result) or result))
            else:
                move_line_res = abs(line_total_in_company_currency)
 
            res[move_line.id]['amount_res'] = move_line_res
        return res

    _columns = {
        'is_depo_main': fields.boolean('Main Deposit Value'),
        'is_depo': fields.boolean('Deposit Value'),
        'exrate': fields.float('ExRate', digits=(12,6)),
        'is_refund': fields.boolean('Refund Value'),
        'move_name': fields.related('move_id', 'name', string='Move Name', type='char', size=64),
        'currency': fields.function(_currency, string='Currency',
            type='many2one', relation='res.currency'),
        'amount_residual_currency': fields.function(_amount_residual, string='Residual Amount', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in its currency (maybe different of the company currency)."),
        'amount_original': fields.function(_amount_residual, string='Amount Original', multi="residual", help="The original amount on a receivable or payable of a journal entry."),
        'amount_residual': fields.function(_amount_residual, string='Residual Amount', multi="residual", help="The residual amount on a receivable or payable of a journal entry expressed in the company currency."),
        'amount_res': fields.function(_amount_residual, string='Amount Res', multi="residual", help="The residual amount on a receivable or payable of a journal entry."),
    }

account_move_line()

class account_journal(osv.osv):
    _inherit = "account.journal"
    _columns = {
        'property_bank_charges': fields.property(
            type='many2one',
            relation='account.account',
            string ='Bank Charges Account'),
    }

account_journal()

class account_account(osv.osv):
    _inherit = 'account.account'
    _description = 'Account'

    _columns = {
        'pl_type': fields.selection([
            ('income', 'Main Income (P&L)'),
            ('expense', 'Main Expense (P&L)'),
            ('other_income', 'Other Income (P&L)'),
            ('other_expense', 'Other Expense (P&L)'),
            ('equity', 'EQUITY (BS)'),
            ('fixed_asset', 'FIXED ASSET (BS)'),
            ('accumulated', 'ACCUMULATED DEPRN (BS)'),
            ('investment', 'INVESTMENT (BS)'),
            ('curr_asset', 'CURRENT ASSET (BS)'),
            ('curr_liabilities', 'CURRRENT LIABILITIES (BS)'),
        ], 'P&L / BS Type'),
    }

class res_company(osv.osv):
    _inherit = 'res.company'

    _columns = {
        'property_currency_gain_loss': fields.property(
            type='many2one',
            relation='account.account',
            string ='Currency Gain Loss Account'),
    }

res_company()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
